use bliquez::{
    math::Rect2D, misc::SpriteBatch, Context, Material, Pixel, Pixmap, Scene, COLOR_WHITE,
};
use cgmath::{vec2, Matrix4, Rad, SquareMatrix};
use image::GenericImageView;
use winit::{
    dpi::PhysicalSize,
    event::{Event, WindowEvent},
    event_loop::{ControlFlow, EventLoop},
    window::WindowBuilder,
};

fn main() {
    let el = EventLoop::new().unwrap();
    let window = WindowBuilder::new()
        .with_title("Image")
        .with_inner_size(PhysicalSize {
            width: 800,
            height: 800,
        })
        .build(&el)
        .unwrap();

    let terrain = image::load_from_memory(include_bytes!("terrain.png")).unwrap();
    let (width, height) = terrain.dimensions();

    let pixmap = Pixmap::from_pixels(
        terrain
            .pixels()
            .map(|(_, _, p)| Pixel::from_rgba_array(p.0)),
        width,
        height,
    );

    let mut ctx = Context::new(&window, 800, 800);

    let mut scene = Scene::new(wgpu::Color::BLACK);
    scene.put_global(
        0,
        Material::builder()
            .unifrom(&ctx, Matrix4::<f32>::identity(), wgpu::ShaderStages::VERTEX)
            .build(&ctx),
    );

    let mut batch = SpriteBatch::new(&ctx, &scene, pixmap);

    batch.add_sprite(
        vec2(-0.5, -0.5),
        1.0,
        1.0,
        Rect2D::new(0.25, 0.3125, 0.0625, 0.0),
        COLOR_WHITE,
    );

    scene.add_brick("batch", batch);

    let mut theta = 0.0;

    el.set_control_flow(ControlFlow::Poll);
    el.run(|event, target| match event {
        Event::WindowEvent {
            event: WindowEvent::CloseRequested,
            ..
        } => target.exit(),
        Event::AboutToWait => {
            theta += 0.0001;
            scene
                .get_brick_mut::<SpriteBatch>("batch")
                .unwrap()
                .set_model_matrix(Matrix4::from_angle_z(Rad(theta)));

            window.request_redraw();
        }
        Event::WindowEvent {
            event: WindowEvent::KeyboardInput { event, .. },
            ..
        } => if event.state.is_pressed() {},
        Event::WindowEvent {
            event: WindowEvent::Resized(size),
            ..
        } => {
            ctx.resize(size.width, size.height);
        }
        Event::WindowEvent {
            event: WindowEvent::RedrawRequested,
            ..
        } => ctx.render_scene(&mut scene),
        _ => (),
    })
    .unwrap();
}
